home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Graphics Plus
/
Graphics Plus.iso
/
general
/
modelers
/
geomview
/
source.lha
/
Geomview
/
src
/
bin
/
4dview
/
4dstuff.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-08-18
|
15KB
|
714 lines
#include "4dstuff.h"
extern "C" {
#include "ooglwrap.h"
}
/* Clipper 1.0 */
/* by Daeron */
double WMAX=0.0,WMIN=0.0;
/* ends of color spectrum used for 4th coordinate */
float R_0=0, G_0=0, B_0=1;
float R_1=1, G_1=0, B_1=0;
/*****************************************************************************/
void err_msg(char *errmsg)
{
fprintf(stderr,"%s\n",errmsg);
}
/*****************************************************************************/
/* Class initializers */
vertex::vertex()
{
x=0.0;y=0.0;z=0.0;w=0.0;r=0.5;g=0.5;b=0.5;a=0.5;clip=0;num=0;next=NULL;
}
vertex_list::vertex_list()
{
numvtx=0;head=NULL;
colorscheme = 0;
coloron = 0;
projection=1;
}
pvtx::pvtx()
{
num=0;next=NULL;
}
polyvtx_list::polyvtx_list()
{
numvtx=0;head=NULL;
}
poly::poly()
{
numvtx=0;me=NULL;next=NULL;clipped=0;
}
poly_list::poly_list()
{
numpoly=0;head=NULL;
}
/*****************************************************************************/
void vertex_list::clip_vertex(double a1, double b1, double c1,
double d1, double e1, int side1)
{
double tmp,tmp2;
side=side1;
a=a1;b=b1;c=c1;d=d1;e=e1;
point = head;
while (point!=NULL)
{
tmp = a*(point->x) + b*(point->y) + c*(point->z) + d*(point->w);
tmp2 = tmp-e;
if (tmp2<0) tmp2 = tmp2*(-1.0);
if (tmp2>.00001)
{
if ((tmp<e)&&(side==1))
point->clip=1;
else
if ((tmp>e)&&(side==0))
point->clip=1;
}
point = point->next;
}
}
/*****************************************************************************/
void vertex_list::put_in_array(vertex **vertex_set)
{
int count=0;
point = head;
while (point!=NULL)
{
vertex_set[count] = point;
point->num = count;
point=point->next;
count++;
}
numvtx = count;
}
/*****************************************************************************/
vertex *vertex_list::add_vertex(double x, double y, double z, double w)
{
vertex *temp = head;
head = new vertex;
head->next = temp;
head->x = x; head->y = y; head->z = z; head->w = w;
head->clip = 0;
return (head);
}
/*****************************************************************************/
int polyvtx_list::find_unclipped_vertex(vertex **vertex_set)
{
pvtx *temp = head;
int brk=0;
point = head;
do
{
brk = vertex_set[point->num]->clip;
if (brk)
point=point->next;
} while ((brk)&&(point!=temp));
if ((point==temp)&&(brk)) return (1);
head = point;
return (0);
}
/*****************************************************************************/
int polyvtx_list::clip_each_vertex(vertex_list *vtxl, vertex **vertex_set)
{
pvtx *temp, *next, *last;
double t,t1,t2,nx,ny,nz,nw;
double x1,y1,z1,w1;
double x2,y2,z2,w2;
double a = vtxl->a, b = vtxl->b, c = vtxl->c, d = vtxl->d, e = vtxl->e;
last = head;
point = head;
point->me = vertex_set[point->num];
do
{
next = point->next;
next->me = vertex_set[next->num];
x1 = vertex_set[point->num]->x; y1 = vertex_set[point->num]->y;
z1 = vertex_set[point->num]->z; w1 = vertex_set[point->num]->w;
x2 = vertex_set[next->num]->x; y2 = vertex_set[next->num]->y;
z2 = vertex_set[next->num]->z; w2 = vertex_set[next->num]->w;
if ((!(vertex_set[point->num]->clip))&&(vertex_set[next->num]->clip))
{
t1 = (e - a*x1 - b*y1 - c*z1 - d*w1);
t2 = a*(x2 - x1) + b*(y2 - y1) + c*(z2 - z1) + d*(w2 - w1);
if (t2!=0.0)
{
t = t1 / t2;
nx = x1 + t*(x2 - x1); ny = y1 + t*(y2 - y1); nz = z1 + t*(z2 - z1);
nw = w1 + t*(w2 - w1);
temp = new pvtx;
temp->me = vtxl->add_vertex(nx,ny,nz,nw);
numvtx++;
temp->next = next;
point->next = temp;
last = temp;
point = next;
next = point->next;
}
else
{
last = point;
point = next;
next = point->next;
vertex_set[point->num]->clip = 0;
printf("unclip\n");
}
}
else if ((vertex_set[point->num]->clip)&&(vertex_set[next->num]->clip))
{
/*t2 = a*(x2-x1) + b*(y2-y1) + c*(z2-z1) + d*(w2-w1);
if (t2!=0.0)
{*/
last->next = next;
delete point;
numvtx--;
point = next;
next = point->next;
/*}
else
{
printf("AAAA!\n");
last = point;
point = next;
next = point->next;
}*/
}
else if ((vertex_set[point->num]->clip)&&(!(vertex_set[next->num]->clip)))
{
t1 = (e - a*x1 - b*y1 - c*z1 - d*w1);
t2 = a*(x2 - x1) + b*(y2 - y1) + c*(z2 - z1) + d*(w2 - w1);
if (t2!=0.0)
{
t = t1/t2;
nx = x1 + t*(x2 - x1); ny = y1 + t*(y2 - y1); nz = z1 + t*(z2 - z1);
nw = w1 + t*(w2 - w1);
temp = new pvtx;
temp->me = vtxl->add_vertex(nx,ny,nz,nw);
temp->next = next;
last->next = temp;
delete point;
last = temp;
point = next;
next = point->next;
}
else
{
last = point;
vertex_set[point->num]->clip = 0;
point = next;
next = point->next;
printf("unclip2\n");
}
}
else
{
last=point;
point=next;
next=point->next;
}
} while (point!=head);
return numvtx;
}
/*****************************************************************************/
void poly::clip_poly(vertex_list *vtxl, vertex **vertex_set)
{
clipped = me->find_unclipped_vertex(vertex_set);
if (clipped) return;
numvtx = me->clip_each_vertex(vtxl,vertex_set);
}
/*****************************************************************************/
void poly_list::clip_polys(vertex_list *vtxl)
{
int count=0;
vertex **vertex_set;
vertex_set = new vertex*[vtxl->numvtx];
vtxl->put_in_array(vertex_set);
point = head;
while (point!=NULL)
{
point->clip_poly(vtxl,vertex_set);
point=point->next;
}
delete vertex_set;
}
/*****************************************************************************/
void vertex::read_vertex4d(int count, FILE *fin, int coloron)
{
char nxtc;
r = 0.5; g = 0.5; b = 0.5; a = 1.0;
/* fprintf(stderr,"reading 4vertices - color = %d\n",coloron);*/
if (coloron)
fscanf(fin,"%lf %lf %lf %lf %lf %lf %lf %lf",&x,&y,&z,&w,&r,&g,&b,&a);
else
fscanf(fin,"%lf %lf %lf %lf",&x,&y,&z,&w);
/* fprintf(stderr,"%lf %lf %lf %lf -> %lf %lf %lf %lf\n",x,y,z,w,r,g,b,a);*/
num=count;
if (x<WMIN) WMIN=x;
if (y<WMIN) WMIN=y;
if (z<WMIN) WMIN=z;
if (w<WMIN) WMIN=w;
if (x>WMAX) WMAX=x;
if (y>WMAX) WMAX=y;
if (z>WMAX) WMAX=z;
if (w>WMAX) WMAX=w;
nxtc = ' ';
while (nxtc!='\n')
nxtc = (char)fgetc(fin);
}
/*****************************************************************************/
void vertex::read_vertex(int count, FILE *fin, int coloron)
{
char nxtc;
r = 0.5; g = 0.5; b = 0.5; a = 1.0;
/* fprintf(stderr,"reading 3vertices - color = %d\n",coloron);*/
if (coloron)
fscanf(fin,"%lf %lf %lf %lf %lf %lf %lf",&x,&y,&z,&r,&g,&b,&a);
else
fscanf(fin,"%lf %lf %lf",&x,&y,&z);
w = 1.0;
/* fprintf(stderr,"%lf %lf %lf -> %lf %lf %lf %lf\n",x,y,z,r,g,b,a);*/
num=count;
if (x<WMIN) WMIN=x;
if (y<WMIN) WMIN=y;
if (z<WMIN) WMIN=z;
if (w<WMIN) WMIN=w;
if (x>WMAX) WMAX=x;
if (y>WMAX) WMAX=y;
if (z>WMAX) WMAX=z;
if (w>WMAX) WMAX=w;
nxtc = ' ';
while (nxtc!='\n')
nxtc = (char)fgetc(fin);
}
/*****************************************************************************/
void vertex_list::read_vertices(int numvx, FILE *fin)
{
int count;
vertex *old;
WMAX=0.0;
WMIN=0.0;
numvtx = numvx;
point = new vertex;
if (vtype==4)
point->read_vertex4d(0,fin,coloron);
else
point->read_vertex(0,fin,coloron);
head = point;
old = point;
for (count=1;count<numvtx;count++)
{
point = new vertex;
old->next = point;
if (vtype==4)
point->read_vertex4d(count,fin,coloron);
else
point->read_vertex(count,fin,coloron);
old = point;
}
point->next = NULL;
}
/*****************************************************************************/
void pvtx::read_pvtx(FILE *fin)
{
fscanf(fin,"%d",&num);
}
/*****************************************************************************/
void polyvtx_list::read_polyvtx(int numvx, FILE *fin)
{
int count;
pvtx *old;
char temp;
numvtx = numvx;
point = new pvtx;
point->read_pvtx(fin);
head = point;
old = point;
for (count=1;count<numvtx;count++)
{
point = new pvtx;
old->next = point;
point->read_pvtx(fin);
old = point;
}
point->next = head;
fscanf(fin,"%c",&temp);
while ((temp!='\n')&&(!feof(fin)))
fscanf(fin,"%c",&temp);
}
/*****************************************************************************/
void poly::read_poly(FILE *fin)
{
fscanf(fin,"%d ",&numvtx);
me = new polyvtx_list;
me->read_polyvtx(numvtx,fin);
}
/*****************************************************************************/
void poly_list::read_polys(int numpl, FILE *fin)
{
int count;
poly *old;
numpoly = numpl;
point = new poly;
point->read_poly(fin);
head = point;
old = point;
for (count=1;count<numpoly;count++)
{
point = new poly;
old->next = point;
point->read_poly(fin);
old = point;
}
point->next = NULL;
}
/*****************************************************************************/
void vertex_list::refresh_vertex_list()
{
int count = 0;
vertex *prev;
point = head;
if (point!=NULL)
while ((point->clip)&&(point->next!=NULL))
{
prev = point;
point = point->next;
delete prev;
head = point;
}
if (point!=NULL)
{
point->num = count;
count++;
prev = point;
point = point->next;
}
while (point!=NULL)
{
if (!(point->clip))
{
prev = point;
point->num = count;
count++;
}
else
{
prev->next = point->next;
delete point;
point = prev;
}
point=point->next;
}
numvtx=count;
}
/*****************************************************************************/
void poly_list::refresh_poly_list()
{
int count = 0;
poly *prev;
point = head;
if (point!=NULL)
while ((point->clipped)&&(point->next!=NULL))
{
prev = point;
point = point->next;
delete prev;
head = point;
}
count++;
if (point==NULL) count=0;
prev = point;
point = point->next;
while (point!=NULL)
{
if (!(point->clipped))
{
prev = point;
count++;
}
else
{
prev->next = point->next;
delete point;
point = prev;
}
point=point->next;
}
numpoly=count;
}
/*
void poly_list::refresh_poly_list()
{
int count = 0;
point = head;
while (point!=NULL)
{
if (!(point->clipped))
count++;
point=point->next;
}
numpoly=count;
}*/
/*****************************************************************************/
int load_off_file(poly_list *polyhedron, vertex_list *polyvertex,
char *name, char *filename)
{
FILE *fin,*fout;
char toss[256];
char nxtc;
int vrtx,face,edge;
system("rm -f /tmp/xx4dtmp");
if (!(fin=fopen(name,"r")))
{
err_msg("Could not open input file.");
return (0);
}
if (!(fout=fopen("/tmp/xx4dtmp","w")))
{
err_msg("Couldn\'t use tmp directory.\n");
return (0);
}
fclose(fout); fclose(fin);
CCWrap(name,"/tmp/xx4dtmp");
if (!(fin=fopen("/tmp/xx4dtmp","r")))
{
err_msg("Couldn\'t use tmp directory.\n");
return (0);
}
nxtc = ' ';
while (nxtc!='=')
nxtc = fgetc(fin);
fgetc(fin);
nxtc = fgetc(fin);
if (nxtc!='4')
polyvertex->vtype=3;
else
polyvertex->vtype=4;
fscanf(fin,"%s\n",toss);
if ((toss[0] == 'C') || (nxtc == 'C'))
polyvertex->coloron = 1;
else
polyvertex->coloron = 0;
if (toss[0] == '4')
polyvertex->vtype = 4;
/*
fprintf(stderr,
"File type: %d%s - %d\n",polyvertex->vtype,toss,polyvertex->coloron);
*/
sprintf(filename,"%s",name);
fscanf(fin,"%d %d %d\n\n",&vrtx,&face,&edge);
if ((vrtx==0)||(face==0) /*||(edge==0)*/)
{
//err_msg("Bad parameters.");
return (0);
}
polyvertex->read_vertices(vrtx,fin);
polyhedron->read_polys(face,fin);
system("rm -f /tmp/xx4dtmp");
return(1);
}
/*****************************************************************************/
void vertex_list::write_vertices(FILE *fout)
{
point=head;
while(point!=NULL)
{
if (!(point->clip))
fprintf(fout,"\t%lf %lf %lf %lf\n",point->x,point->y,point->z,point->w);
point=point->next;
}
}
/*****************************************************************************/
void vertex_list::setproj(int proj)
{
projection = proj;
}
/*****************************************************************************/
void vertex_list::write_vertices3d(FILE *fout, float T[4][4], clip_plane *clipper)
{
float x,y,z,w;
float xo,yo,zo,wo;
float rd,gr,bl,wrng;
float depth;
wrng=(float)(WMAX-WMIN);
/* transform, color, and ship out the vertices */
point=head;
while(point!=NULL)
{
if (!(point->clip))
{
x=(float)point->x,y=(float)point->y,z=(float)point->z,
w=(float)point->w;
xo = x*T[0][0] + y*T[0][1] + z*T[0][2] + w*T[0][3];
yo = x*T[1][0] + y*T[1][1] + z*T[1][2] + w*T[1][3];
zo = x*T[2][0] + y*T[2][1] + z*T[2][2] + w*T[2][3];
wo = x*T[3][0] + y*T[3][1] + z*T[3][2] + w*T[3][3];
rd = (wo-WMIN)/wrng;
bl = 1.0-rd;
if (projection)
{
/* perspective distortion */
xo = xo/(rd*2.0+1.0);
yo = yo/(rd*2.0+1.0);
zo = zo/(rd*2.0+1.0);
}
if (colorscheme)
{
gr = 0.0;
if (rd<0.0) rd=0.0;
if (rd>1.0) rd=1.0;
if (bl<0.0) bl=0.0;
if (bl>1.0) bl=1.0;
}
else
{
rd=(float)point->r;
gr=(float)point->g;
bl=(float)point->b;
}
depth = x*(float)clipper->ax + y*(float)clipper->by +
z*(float)clipper->cz + w*(float)clipper->dw;
if ((depth > ((float)clipper->depth)+.00001)) {rd=1.0;gr=1.0;bl=1.0;}
fprintf(fout,"%f %f %f\t%f %f %f 1\n", xo,yo,zo,rd,gr,bl);
}
point=point->next;
}
}
/*****************************************************************************/
void polyvtx_list::write_polyvtx(FILE *fout)
{
pvtx *temp;
temp=head;
point=head;
fprintf(fout,"\t%d",numvtx);
do
{
fprintf(fout," %d",point->me->num);
point->num = point->me->num;
point=point->next;
} while (point!=temp);
fprintf(fout,"\n");
}
/*****************************************************************************/
void poly_list::write_polys(FILE *fout)
{
point=head;
while(point!=NULL)
{
if (!(point->clipped))
point->me->write_polyvtx(fout);
point=point->next;
}
}
/*****************************************************************************/
void store_off_file(poly_list *polyhedron, vertex_list *polyvertex,
char *storename)
{
FILE *fout = NULL;
storename = NULL;
//if (!(fout=fopen(storename,"w"))) err_msg("Couldn\'t save to output file.\n");
fprintf(fout,"4OFF\n %d %d 1\n",polyvertex->numvtx,polyhedron->numpoly);
polyvertex->write_vertices(fout);
polyhedron->write_polys(fout);
}
/*****************************************************************************/
clip_plane::clip_plane()
{
ax=0;by=0;cz=0;dw=0;depth=10000.0;
}
/*****************************************************************************/
void sliderval(float *a, float *b)
{
*a = (float)WMIN;
*b = (float)WMAX;
}